package com.demo.javaDemo.concurrent;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.function.Predicate;

public class FileCounter extends RecursiveTask<Long> {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private final static ForkJoinPool forkJoinPool = new ForkJoinPool();

	final File dir;
	final Predicate<File> test;

	public FileCounter(final File dir, Predicate<File> test) {
		this.dir = dir;
		this.test = test;
	}

	@Override
	public Long compute() {
		long rs = 0;
		final File[] files = dir.listFiles();
		if(files==null) {
			System.out.println(dir.getAbsolutePath()+">>>>>"+rs);
			return rs;
		}
		int len = files.length;
		if (len > 0) {
			List<ForkJoinTask<Long>> tasks = new ArrayList<ForkJoinTask<Long>>(len);
			for (final File file : files) {
				if (file.isDirectory()) {
					tasks.add(new FileCounter(file, test));
				} else {
					if (test.test(file)) {
						rs += 1;
					}
				}
			}
			if (!tasks.isEmpty()) {
				for (final ForkJoinTask<Long> task : invokeAll(tasks)) {
					rs += task.join();
				}
			}
		}
//		System.out.println(dir.getAbsolutePath()+">>>>>"+rs);
		return rs;
	}
	public static Long count(File dir, Predicate<File> test) {
		return forkJoinPool.invoke(new FileCounter(dir, test));
	}
	public static void main(final String[] args) {
		File path = new File("F:\\gitWorkspace\\mayun\\demo\\");
		final long start = System.nanoTime();
		System.out.println(FileCounter.count(path, f -> f.getName().endsWith(".java")));
		System.out.println("Time taken: " + (System.nanoTime() - start) / 1.0e6);
	}
}